from datetime import datetime
from typing import List, Optional
from typing import List
from app.schemas.base.login import CredentialsSchema
from app.utils.request import RequestHandler
##密码 
from app.utils.user import get_password_hash, verify_password
from app.models.base.user import User,Role
from app.schemas.base.error_code import *
from app.core.exceptions import BusinessError
from app.utils.user import verify_password, create_access_token_with_expiry, get_password_hash
from app.core.config import settings

from app.schemas.base.user import RoleCreate, RoleUpdate,UserCreate, UserUpdate
from app.core.crud import CRUDBase
from app.models.origin.api import Api
from app.models.origin.menus import Menu
from app.models.base.user import User,Role
from app.utils.app_log import logger


## 角色服务器
class RoleService(CRUDBase[Role, RoleCreate, RoleUpdate]):
    def __init__(self):
        super().__init__(model=Role)

    async def is_exist(self, name: str) -> bool:
        return await self.model.filter(name=name).exists()
    
    async def update_user_roles(self, user: User, role_data: List[Dict]) -> None:
        # 先删除现有角色
        await self.model.filter(user=user).delete()
        # 创建新角色
        for data in role_data:
            await self.model.create(
                user=user,
                family_id=data.get("family_id"),
                role_type=data["role_type"]
            )


## 用户角色
role_service = RoleService()


# app/services/base/user.py
class UserService(CRUDBase[User, UserCreate, UserUpdate]):
    def __init__(self):
        super().__init__(model=User)

    async def authenticate_and_login(self, credentials: CredentialsSchema):
        ## 数据库真实获取
        user = await self.authenticate(credentials)

        if not user or not verify_password(credentials.password, user.password):
            # 抛出业务异常 登录失败
            raise BusinessError(RESOURCE_ACCESS_DENIED.format(resource = "用户登录"),
                                f"""用户{credentials.username} 不存在，登录失败""")
        
        active_uf = await user.user_families.filter(is_active=True).first()
        if active_uf:
            family_id = active_uf.family_id
        # 创建JWT payload
        jwt_payload = {
            "user_id": user.id,
            "username": user.username,
            "is_superuser": user.is_superuser,
            "family_id": family_id,
        }
        logger.info(f"用户{jwt_payload['family_id']} 登录成功")
        # 创建token
        token = create_access_token_with_expiry(data=jwt_payload)
        await self.update_last_login(user.id)  #更新登录时间
        ## 构造返回数据
        data = {
            "user_id": user.id,
            "familiy_id": family_id,
            "access_token": token,
            "token_type": "bearer",
            "username": user.username,
            "expires_in": settings.JWT_ACCESS_TOKEN_EXPIRE_MINUTES * 60,
            "is_superuser": user.is_superuser
        }
        return data
    
    async def authenticate(self, credentials: CredentialsSchema) -> Optional["User"]:
        user = await self.model.filter(username=credentials.username).first()
        if not user:
            raise BusinessError(RESOURCE_NOT_FOUND.format(resource = "用户"),details= "用户不存在!")  
        verified = verify_password(credentials.password, user.password)
        if not verified:
            raise BusinessError(VALIDATION_ERROR, details="密码错误!")
        if not user.is_active:
            raise BusinessError(RESOURCE_ACCESS_DENIED.format(resource = "用户"), details="用户已被禁用")
        return user
    
    async def get_by_email(self, email: str) -> Optional[User]:
        return await self.model.filter(email=email).first()

    async def get_by_username(self, username: str) -> Optional[User]:
        return await self.model.filter(username=username).first()

    async def create_user(self, obj_in: UserCreate) -> User:
        obj_in.password = get_password_hash(password=obj_in.password)
        obj = await self.create(obj_in)
        return obj

    async def user_login(self, credentials: CredentialsSchema) -> Optional["User"]:
        data = await user_service.authenticate(credentials)
        return data

    ## 更新 信息
    async def update_roles(self, user: User, role_data: List[Dict]) -> None:
        # role_ids 改成角色表 
        # role_data = [{"role_type": "user","family_id": 1}]
        await role_service.update_user_roles(user, role_data)

    async def reset_password(self, user_id: int):
        user_obj = await self.get(id=user_id)
        if user_obj.is_superuser:
            raise BusinessError(RESOURCE_ACCESS_DENIED,detailss="您无权重置超级管理员密码")
        user_obj.password = get_password_hash(password="123456")
        await user_obj.save()


    async def update_last_login(self, id: int) -> None:
        ## 更新登录时间
        user = await self.model.get(id=id)
        user.last_login = datetime.now()
        await user.save()


user_service = UserService()